﻿using System.ComponentModel;
using System.Drawing.Design;
using System.Text;
using System.Web.UI;
using System.Xml.Linq;

namespace SPAdaptiveMenu.Controls
{
    /// <summary>
    /// Menu containing nested menu
    /// </summary>
    [DefaultProperty("ItemCollection"),
     ParseChildren(true, "ItemCollection")]
    public class MenuNested : MenuItem
    {
        ///<summary>
        ///</summary>
        [Category("Behavior"),
         Description("The menu items collection"),
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
         Editor(typeof(MenuItemCollectionEditor), typeof(UITypeEditor)),
         PersistenceMode(PersistenceMode.InnerProperty)]
        public MenuItemCollection ItemCollection
        {
            get { return _itemCollection ?? (_itemCollection = new MenuItemCollection()); }
            set { _itemCollection = value; }
        }
        private MenuItemCollection _itemCollection;

        public override MenuItemType ItemType
        {
            get { return MenuItemType.SubMenu; }
        }

        ///<summary>
        ///</summary>
        public MenuNested()
        {
            _itemCollection = new MenuItemCollection();
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            foreach (MenuItem item in ItemCollection)
            {
                Controls.Add(item);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            var sb = new StringBuilder();
            sb.AppendFormat(@"<ie:menuitem id=""{0}"" type=""submenu""", ClientID);
            if (!string.IsNullOrEmpty(Title))
                sb.AppendFormat(@" title=""{0}""", Title);
            if (!string.IsNullOrEmpty(IconToolTip))
                sb.AppendFormat(@" iconAltText=""{0}""", IconToolTip);
            if (!string.IsNullOrEmpty(IconSrc))
                sb.AppendFormat(@" iconSrc=""{0}""", IconSrc);
            if (!string.IsNullOrEmpty(Description))
                sb.AppendFormat(@" description=""{0}""", Description);
            if (!string.IsNullOrEmpty(Title))
                sb.AppendFormat(@" text=""{0}""", Title);
            if (Disabled)
                sb.Append(@" enabled=""false""");
            sb.Append(@"><ie:menuitem type=""label""></ie:menuitem>");
            writer.Write(sb.ToString());
            RenderChildren(writer);
            writer.Write("</ie:menuitem>");
        }

        protected internal override XElement Serialized
        {
            get
            {
                var element = base.Serialized;
                element.Add(new XAttribute("Type", ItemType));
                return element;
            }
        }

        protected override object SaveControlState()
        {
            base.SaveControlState();
            var obj = base.SaveControlState();
            return obj != null
                ? (object)new Pair(obj, Serialized.ToString())
                : Serialized.ToString();
        }

        protected override void LoadControlState(object state)
        {
            if (state == null) return;
            var p = state as Pair;
            if (p != null)
            {
                base.LoadControlState(p.First);
                InitProperties(XElement.Parse((string)p.Second));
            }
            else
            {
                if (state is string)
                    InitProperties(XElement.Parse((string)state));
                else
                    base.LoadControlState(state);
            }
        }

        protected internal override XElement HTML
        {
            get
            {
                var element = base.HTML;
                element.Add(new XAttribute("type", "submenu"));
                element.Add(new XElement("menuitem", new XAttribute("type", "label")));
                foreach (MenuItem item in ItemCollection)
                {
                    element.Add(item.HTML);
                }
                return element;
            }
        }
    }
}
